//
//  COChatViewController.swift
//  CocoProject
//
//  Created by Vill on 2023/11/10.
//

import UIKit
import IQKeyboardManagerSwift

class COChatViewController: RCConversationViewController,UITextViewDelegate {
    
    private var textViewBottomConstraint: NSLayoutConstraint!   // 间距
    
    override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(animated)
        IQKeyboardManager.shared.enable = false
        IQKeyboardManager.shared.enableAutoToolbar = false
    }
    
    override func viewWillDisappear(_ animated: Bool) {
        super.viewWillDisappear(animated)
        IQKeyboardManager.shared.enable = true
        IQKeyboardManager.shared.enableAutoToolbar = true
    }
    
    lazy var navView :UIView = {
        let nav = UIView()
        return nav
    }()
    
    lazy var containView: UIView = {
        let con = UIView()
        con.backgroundColor = UIColor.white
        return con
    }()
    
    lazy var bgImg: UIImageView = {
        let nav = UIImageView()
        nav.image = KImaged("coco_main_bg")
        nav.contentMode = .scaleAspectFill
        nav.clipsToBounds = true
        return nav
    }()
    
    lazy var backBtn :UIButton = {
        let back = UIButton()
        back.setImage(KImaged("coco_base_fanhui"), for: .normal)
        back.addTap { [weak self] ges in
            guard let `self` = self else { return }
            self.navigationController?.popViewController(animated: true)
        }
        return back
    }()
    
    lazy var nameLbl:UILabel = {
        let lbl = UILabel()
        lbl.font = UIFont.pingfangFont(ofSize: PTW(16), weight: .medium)
        lbl.textColor = UIColor.white
        lbl.numberOfLines = 0
        lbl.textAlignment = .center
        return lbl
    }()
    
    lazy var perCoinLbl:UILabel = {
        let lbl = UILabel()
        let markAttribute = NSMutableAttributedString(string: "2/msg")
        let attr: [NSAttributedString.Key : Any] = [.foregroundColor: UIColor.white,.font : UIFont.systemFont(ofSize: CGFloat(PTW(14)), weight: .regular)]
        markAttribute.addAttributes(attr, range: NSRange(location: 0, length: 5))
        //以上是富文本显示
        let markattch = NSTextAttachment() //定义一个attachment
        markattch.image = UIImage(named: "coco_mine_star")//初始化图片
        markattch.bounds = CGRect(x: 0, y: -PTW(3) , width: PTW(14) , height:PTW(14)) //初始化图片的 bounds
        let markattchStr = NSAttributedString(attachment: markattch) // 将attachment  加入富文本中
        markAttribute.insert(markattchStr, at: 0)// 将markattchStr  加入原有文字的某个位置
        lbl.attributedText = markAttribute
        return lbl
    }()
    
    lazy var moreBtn :UIButton = {
        let back = UIButton()
        back.setImage(KImaged("coco_profile_more"), for: .normal)
        back.addTarget(self, action: #selector(showTip), for: .touchUpInside)
        return back
    }()
    
    // 聊天容器
    lazy var inputToolbar: UIView = {
        let input = UIView()
        input.backgroundColor = UIColor.clear
        input.translatesAutoresizingMaskIntoConstraints = false
        return input
    }()
    
    // 输入框
    lazy var textView: GrowingTextView = {
        let txtView = GrowingTextView()
        txtView.delegate = self
        txtView.maxLength = 300
        txtView.maxHeight = PTW(70)
        txtView.minHeight = PTW(50)
        txtView.textColor = UIColor.colorWithHex("#7863A6", 1)
        txtView.backgroundColor = UIColor.colorWithHex("#F5F5F5")
        txtView.layer.cornerRadius = PTW(25)
        txtView.layer.masksToBounds = true
        txtView.trimWhiteSpaceWhenEndEditing = true
        txtView.placeholder = "Write here"
        txtView.placeholderColor = UIColor.colorWithHex("#7863A6", 0.5)
        txtView.font = UIFont.pingfangFont(ofSize: PTW(15), weight: .medium)
        txtView.returnKeyType = .send
        txtView.enablesReturnKeyAutomatically = true
        txtView.translatesAutoresizingMaskIntoConstraints = false
        // 使用textContainerInset设置top、left、right
        txtView.textContainerInset = UIEdgeInsets(top: PTW(15), left: PTW(15), bottom: 0, right: PTW(10))
        //当光标在最后一行时，始终显示低边距，需使用contentInset设置bottom.
        txtView.contentInset = UIEdgeInsets(top: 0, left: 0, bottom: PTW(10), right: 0)
        //防止在拼音打字时抖动
        txtView.layoutManager.allowsNonContiguousLayout = false
        return txtView
    }()
    
    // 礼物按钮
    lazy var giftBtn: UIButton = {
        let gift = UIButton(type: .custom)
        gift.setImage(KImaged("coco_msg_gift"), for: .normal)
        gift.translatesAutoresizingMaskIntoConstraints = false
        gift.addTarget(self, action: #selector(giftAction), for: .touchUpInside)
        return gift
    }()
    
    lazy var videoBtn: COChatDragView = {
        let btn = COChatDragView(frame: .zero)
        btn.addTap {[weak self] ges in
            self?.videoAction()
        }
        return btn
    }()
    
    lazy var iconImg: UIImageView = {
        let nav = UIImageView()
        nav.contentMode = .scaleAspectFill
        nav.layer.cornerRadius = 20
        nav.clipsToBounds = true
        return nav
    }()

    override func viewDidLoad() {
        super.viewDidLoad()
        self.view.backgroundColor = .white
        conversationMessageCollectionView.backgroundColor = .clear
        //隐藏输入框并修改背景色
        if (self.chatSessionInputBarControl != nil){
            self.chatSessionInputBarControl.isHidden = true
            if (self.chatSessionInputBarControl.safeAreaView != nil){
                self.chatSessionInputBarControl.safeAreaView.isHidden = true
            }
        }
        xl_prefersNavigationBarHidden = true
        xl_interactivePopMaxAllowedInitialDistanceToLeftEdge = PTW(200)
        
        self.view.addSubview(self.bgImg)
        self.bgImg.addSubview(self.containView)
        self.bgImg.snp.makeConstraints { make in
            make.edges.equalToSuperview()
        }
        self.containView.snp.makeConstraints { make in
            make.left.right.bottom.equalToSuperview()
            make.top.equalToSuperview().offset(KStatusAndNavBarHeight + PTW(10))
        }
        self.view.sendSubviewToBack(self.bgImg)
        self.setUpNavView()
        if self.conversationType == .ConversationType_SYSTEM{
            moreBtn.isHidden = true
            self.nameLbl.text = "Activity"
            self.iconImg.image = KImaged("coco_msg_system")
            conversationMessageCollectionView.frame = CGRect(x: 0, y: KStatusAndNavBarHeight + PTW(10), width: SCREENWIDTH, height: SCREENHEIGHT - KStatusAndNavBarHeight - PTW(10))
            conversationMessageCollectionView.contentInset = UIEdgeInsets(top: PTW(10), left: PTW(0), bottom: PTW(20), right: PTW(0))
        }else{
            moreBtn.isHidden = false
            // 隐藏工具栏
            chatSessionInputBarControl.isHidden = true
            conversationMessageCollectionView.contentInset = UIEdgeInsets(top: PTW(10), left: PTW(0), bottom: PTW(0), right: PTW(0))
            RCIM.shared().userInfoDataSource.getUserInfo(withUserId: self.targetId) { [unowned self] (userInfo) in
                let feed = kFeedbackVer.keyGetNSDefaultsKey() as? Bool
                self.iconImg.sd_setUrlImage(userInfo?.portraitUri, placeholder: KImaged("coco_icon_holder"))
                if feed == true{
                    self.nameLbl.text = userInfo?.name
                }else{
                    var str = ""
                    if let dictionary = stringToDictionary(jsonString: userInfo?.name ?? "") {
                        str = "\(dictionary["name"] as? String ?? "")"
                    }else{
                        str = "\(userInfo?.name ?? "")"
                    }
                    self.nameLbl.text = str
//                    let markAttribute = NSMutableAttributedString(string: str)
//                    let attr: [NSAttributedString.Key : Any] = [.foregroundColor: UIColor.white,.font : UIFont.systemFont(ofSize: CGFloat(PTW(13)), weight: .regular)]
//                    markAttribute.addAttributes(attr, range: NSRange(location: str.count - 5, length: 5))
//                    //以上是富文本显示
//                    let markattch = NSTextAttachment() //定义一个attachment
//                    markattch.image = UIImage(named: "coco_mine_star")//初始化图片
//                    markattch.bounds = CGRect(x: 0, y: -PTW(1) , width: PTW(10) , height:PTW(10)) //初始化图片的 bounds
//                    let markattchStr = NSAttributedString(attachment: markattch) // 将attachment  加入富文本中
//                    markAttribute.insert(markattchStr, at: str.count - 5)// 将markattchStr  加入原有文字的某个位置
//                    let paragraphStyle = NSMutableParagraphStyle()
//                    paragraphStyle.lineSpacing = 0 // 设置行间距为 8 点
//                    markAttribute.addAttribute(NSAttributedString.Key.paragraphStyle, value: paragraphStyle, range: NSMakeRange(0, markAttribute.length))
//                    self.nameLbl.attributedText = markAttribute
                }
            }
            // 设置工具栏
            setToolView()
            getUserStatusInfo()
            view.addSubview(self.videoBtn)
            self.videoBtn.snp.makeConstraints { make in
                make.size.equalTo(CGSize(width: PTW(90), height: PTW(100)))
                make.trailing.equalToSuperview().offset(-PTW(8))
                make.bottom.equalToSuperview().offset(-PTW(80)-KSafeBottomMargin)
            }
        }
        register(COConversationListCell.self, forMessageClass: RCTextMessage.self)
        register(COConversationListCell.self, forMessageClass: RCImageMessage.self)
        register(COConversationListCell.self, forMessageClass: COGiftContent.self)
        register(COConversationListCell.self, forMessageClass: COVideoContent.self)
        self.setNeedsStatusBarAppearanceUpdate()
    }
    
    override func viewDidLayoutSubviews() {
        super.viewDidLayoutSubviews()
        self.containView.clipsCorners(corners: [.topLeft,.topRight], radius: PTW(30))
    }
    
    // MARK: ----------------------- 设置导航栏 -------------------------
    func setUpNavView(){
        view.addSubview(navView)
        navView.addSubview(backBtn)
        navView.addSubview(iconImg)
        navView.addSubview(perCoinLbl)
        navView.addSubview(nameLbl)
        navView.addSubview(moreBtn)
        navView.snp.makeConstraints { make in
            make.leading.top.trailing.equalToSuperview()
            make.height.equalTo(KStatusAndNavBarHeight)
        }
        backBtn.snp.makeConstraints { make in
            make.leading.equalToSuperview()
            make.size.equalTo(PTW(44))
            make.bottom.equalToSuperview()
        }
        iconImg.snp.makeConstraints { make in
            make.leading.equalTo(backBtn.snp.trailing).offset(PTW(20))
            make.size.equalTo(PTW(40))
            make.centerY.equalTo(backBtn)
        }
        perCoinLbl.snp.makeConstraints { make in
            make.leading.equalTo(iconImg.snp.trailing).offset(PTW(10))
            make.bottom.equalTo(iconImg)
        }
        moreBtn.snp.makeConstraints { make in
            make.size.equalTo(backBtn)
            make.trailing.equalToSuperview().offset(-PTW(10))
            make.centerY.equalTo(backBtn)
        }
        nameLbl.snp.makeConstraints { make in
            make.leading.equalTo(iconImg.snp.trailing).offset(PTW(10))
            make.bottom.equalTo(perCoinLbl.snp.top)
        }
    }
    
    // MARK: ----------------------- 设置工具栏 -------------------------
    func setToolView(){
        conversationMessageCollectionView.translatesAutoresizingMaskIntoConstraints = false
        view.addSubview(inputToolbar)
        inputToolbar.addSubview(textView)
        inputToolbar.addSubview(giftBtn)
        
        let collectionBottomConstraint = conversationMessageCollectionView.bottomAnchor.constraint(equalTo: inputToolbar.topAnchor)
        collectionBottomConstraint.priority = UILayoutPriority(600)
        NSLayoutConstraint.activate([
            conversationMessageCollectionView.leadingAnchor.constraint(equalTo: view.leadingAnchor),
            conversationMessageCollectionView.trailingAnchor.constraint(equalTo: view.trailingAnchor),
            conversationMessageCollectionView.topAnchor.constraint(equalTo: view.topAnchor,constant: KStatusAndNavBarHeight + PTW(10)),
            collectionBottomConstraint
        ])
        
        // *** Autolayout ***
        let topConstraint = textView.topAnchor.constraint(equalTo: inputToolbar.topAnchor, constant: PTW(10))
        topConstraint.priority = UILayoutPriority(999)
        NSLayoutConstraint.activate([
            inputToolbar.leadingAnchor.constraint(equalTo: view.leadingAnchor),
            inputToolbar.trailingAnchor.constraint(equalTo: view.trailingAnchor),
            inputToolbar.bottomAnchor.constraint(equalTo: view.bottomAnchor),
            topConstraint
        ])

        if #available(iOS 11, *) {
            textViewBottomConstraint = textView.bottomAnchor.constraint(equalTo: inputToolbar.safeAreaLayoutGuide.bottomAnchor,constant: -PTW(10))
            NSLayoutConstraint.activate([
                textView.leadingAnchor.constraint(equalTo: inputToolbar.safeAreaLayoutGuide.leadingAnchor, constant: PTW(20)),
                textView.trailingAnchor.constraint(equalTo: inputToolbar.safeAreaLayoutGuide.trailingAnchor, constant: -PTW(90)),
                textViewBottomConstraint
                ])
        } else {
            textViewBottomConstraint = textView.bottomAnchor.constraint(equalTo: inputToolbar.bottomAnchor,constant: -PTW(10))
            NSLayoutConstraint.activate([
                textView.leadingAnchor.constraint(equalTo: inputToolbar.leadingAnchor, constant: PTW(20)),
                textView.trailingAnchor.constraint(equalTo: inputToolbar.trailingAnchor, constant: -PTW(90)),
                textViewBottomConstraint
                ])
        }
        
        let bottomConstraint = giftBtn.bottomAnchor.constraint(equalTo: textView.bottomAnchor)
        let trailingConstraint = giftBtn.trailingAnchor.constraint(equalTo: view.trailingAnchor,constant: -PTW(20))
        NSLayoutConstraint.activate([
            giftBtn.heightAnchor.constraint(equalToConstant: PTW(50)),
            giftBtn.widthAnchor.constraint(equalToConstant: PTW(50)),
            bottomConstraint,
            trailingConstraint
            ])
        NotificationCenter.default.addObserver(self, selector: #selector(keyboardWillChangeFrame), name: UIResponder.keyboardWillChangeFrameNotification, object: nil)

        NotificationCenter.default.addObserver(self, selector: #selector(chatEndEditing), name: NSNotification.Name("chatEndEditingNotice"), object: nil)
    }
    
    @objc private func chatEndEditing(){
        self.view.endEditing(true)
    }
    
    @objc private func keyboardWillChangeFrame(_ notification: Notification) {
        if let endFrame = (notification.userInfo?[UIResponder.keyboardFrameEndUserInfoKey] as? NSValue)?.cgRectValue {
            var keyboardHeight = UIScreen.main.bounds.height - endFrame.origin.y
            if #available(iOS 11, *) {
                if keyboardHeight > 0 {
                    keyboardHeight = keyboardHeight - view.safeAreaInsets.bottom
                }
            }
            textViewBottomConstraint.constant = -keyboardHeight - PTW(10)
            view.layoutIfNeeded()
            uploadFrameWithConversations()
        }
    }

    // MARK: ----------------------- 请求个人数据 -------------------------
    func getUserStatusInfo(){
        guard self.targetId.range(of: "_") != nil else {
            return
        }
        let components = self.targetId.components(separatedBy: "_")
        if let lastComponent = components.last {
            var params = [String:Any]()
            params["streamerId"]  = lastComponent
            COHttpManager.request(target: COBaseApi.streamerInfo(param: params), modelType: COChatStreamerInfoModel.self) { [weak self] code, object, success in
                let model = object?.steamer
                if (model?.status == 1){
                    self?.videoBtn.setUpStatusImg(str: "coco_video_online")
                }else if (model?.status == 2){
                    self?.videoBtn.setUpStatusImg(str: "coco_video_busy")
                }else{
                    self?.videoBtn.setUpStatusImg(str: "coco_video_offline")
                }
                self?.videoBtn.setUpPriceLbl(price: model?.price ?? 20)
            } failureBlock: { code, msg in
            }
        }
    }
    
    deinit {
        NotificationCenter.default.removeObserver(self)
    }
    
    //MARK: ---------------- 礼物点击  ---------------
    @objc func giftAction(){
        self.sendGiftMessage { [weak self] model in
            self?.sendGift(with: model)
        }
    }
    
    // MARK: ----------------------- 视频点击 -------------------------
    func videoAction(){
        guard self.targetId.range(of: "_") != nil else {
            return
        }
        let components = self.targetId.components(separatedBy: "_")
        if let lastComponent = components.last {
            print(lastComponent) // 输出
            self.requestStatus(userId:String(lastComponent))
        }
    }
}

//MARK: ---------------- 文本增长代理 ------------------
extension COChatViewController {
    
    func textViewDidChangeHeight(_ textView: GrowingTextView, height: CGFloat) {
        UIView.animate(withDuration: 0.3, delay: 0.0, usingSpringWithDamping: 0.7, initialSpringVelocity: 0.7, options: [.curveLinear], animations: { () -> Void in
            self.view.layoutIfNeeded()
            self.uploadFrameWithConversations()
        }, completion: nil)
    }
    
    func uploadFrameWithConversations() {
        if conversationDataRepository.count > 0{
            let indexPath = IndexPath(item: conversationDataRepository.count - 1, section: 0)
            self.conversationMessageCollectionView.scrollToItem(at: indexPath, at: .bottom, animated: false)
        }
    }
    func textView(_ textView: UITextView, shouldChangeTextIn range: NSRange, replacementText text: String) -> Bool {
        // 发送键&回车键处理
        if (text == "\n") {
            self.sendMessageWithText(textView.text)
            return false
        }
        return true
    }
    
    //MARK: --------------- 发送文本消息 --------------
    func sendMessageWithText(_ message:String){
        guard let user = COUserInfoManager.shared.curUser else {return}
        // 非审核
        let version = kGetJavaVersion.keyGetNSDefaultsKey() as! String
        if (version != KBundleVersion){
            // 1.查询金币是否充足 2.扣费 3.聊天
            if user.userResponse.balance >= 2{
                // 扣币
                guard targetId.range(of: "_") != nil else { return }
                let components = targetId.components(separatedBy: "_")
                if let lastComponent = components.last {
                    var params = [String:Any]()
                    params["streamerId"]  = lastComponent
                    COHttpManager.request(target: COBaseApi.consumeChat(param: params), modelType: COConsumeChatResponseModel.self) { code, object, success in
                        if success == true{
                            AppPurchaseManager.updateBalance()
                        }else{
                            if code == 60667{
                                let balanceAlert = COBalanceAlertView.init(coins: user.userResponse.balance, subtitle: "Need 2 coins for per message")
                                balanceAlert.show()
                                balanceAlert.certainBlock = {
                                    DispatchQueue.main.async {
                                        self.goRechargeWithGift()
                                    }
                                }
                                return
                            }
                        }
                    } failureBlock: { code, msg in
                        UIToolHelper.makeToast("Failed to send,please recharge!")
                        return
                    }
                }
            }else{
                self.view.endEditing(true)
                let balanceAlert = COBalanceAlertView.init(coins: user.userResponse.balance, subtitle: "Need 2 coins for per message")
                balanceAlert.show()
                balanceAlert.certainBlock = {
                    DispatchQueue.main.async {
                        self.goRechargeWithGift()
                    }
                }
                return
            }
        }
        let textMessage = RCTextMessage(content: message)
        let userInfo = RCUserInfo(userId: user.rcUserId, name: user.userResponse.nickName, portrait: user.userResponse.profilePhoto)
        textMessage.senderUserInfo = userInfo
        RCIMClient.shared().sendMessage(.ConversationType_PRIVATE, targetId: self.targetId, content: textMessage, pushContent: "Received a new message", pushData: nil) { (messageId) in
            DispatchQueue.main.async {
                let message = RCMessage(type: .ConversationType_PRIVATE, targetId: self.targetId, direction: .MessageDirection_SEND, content: textMessage)
                let model = RCMessageModel(message: message)
                self.conversationDataRepository.add(model as Any)
                let indexPath = IndexPath(item: self.conversationDataRepository.count - 1, section: 0)
                self.conversationMessageCollectionView.insertItems(at: [indexPath])
                self.conversationMessageCollectionView.scrollToItem(at: indexPath, at: .bottom, animated: false)
                self.textView.text = nil
            }
        } error: { (errorCode, messageId) in
            UIToolHelper.makeToast("Failed to send")
        }
    }
    
    //MARK: --------------- 送礼物 --------------
    func sendGift(with model:COGiftModel){
        guard self.targetId.range(of: "_") != nil else {
            return
        }
        let components = self.targetId.components(separatedBy: "_")
        var params = [String:Any]()
        params["id"]  = model.id
        params["streamerId"]  = components.last
        params["count"]  = 1
        params["giftType"]  = 0
        COHttpManager.request(target: COBaseApi.consumeGift(param: params), modelType: COConsumeGiftResponseModel.self) {[weak self] code, object, success in
            if(success == true){
                var curModel = COUserInfoManager.shared.curUser
                curModel?.userResponse.balance = object?.response.coins ?? 0
                COUserInfoManager.shared.curUser = curModel
                COUserInfoManager.coSaveInfo()
                self?.vertifyGiftWith(model: model)
            }else{
                if code == 60667 || code == 60666{
                    UIToolHelper.makeToast("You don't have enough balance,please recharge")
                    DispatchQueue.main.safeAsync {
                        self?.goRechargeWithGift()
                    }
                }else{
                    UIToolHelper.makeToast("Failed to send")
                }
            }
        } failureBlock: { code, msg in
            print("\(String(describing: msg))")
        }
    }
    
    //MARK: ------------- 赠送礼物扣币成功发送消息 ----------------
    func vertifyGiftWith(model: COGiftModel){
        AppPurchaseManager.updateBalance()
        let curuserModel = COUserInfoManager.shared.curUser
        let giftMsg = COGiftContent()
        giftMsg.id = model.id
        giftMsg.name = model.name
        giftMsg.cover = model.iconUrl
        giftMsg.fileUrl = model.fileUrl
        giftMsg.count = 1
        giftMsg.toStreamerName = self.nameLbl.text
        let userInfo = RCUserInfo(userId: curuserModel!.rcUserId, name: curuserModel?.userResponse.nickName, portrait:curuserModel?.userResponse.profilePhoto)
        giftMsg.senderUserInfo = userInfo
        RCIMClient.shared().sendMessage(.ConversationType_PRIVATE, targetId: self.targetId, content: giftMsg, pushContent: "Receive a gift", pushData: nil) { (messageId) in
            DispatchQueue.main.async {
                let message = RCMessage(type: .ConversationType_PRIVATE, targetId: self.targetId, direction: .MessageDirection_SEND, content: giftMsg)
                let msgModel = RCMessageModel(message: message)
                self.conversationDataRepository.add(msgModel as Any)
                let indexPath = IndexPath(item: self.conversationDataRepository.count - 1, section: 0)
                self.conversationMessageCollectionView.insertItems(at: [indexPath])
                self.conversationMessageCollectionView.scrollToItem(at: indexPath, at: .bottom, animated: false)
                self.playSvga(with: model.fileUrl)
            }
        } error: { (errorCode, messageId) in
            UIToolHelper.makeToast("Failed to send")
        }
    }
    
    private func playSvga(with url: String?) {
        guard url != nil else { return }
        SVGAPlayerUtil.shared.playView = self.view
        SVGAPlayerUtil.shared.fileUrl = url!
    }
}
